#include <android/log.h>
#include "sdlmgr.h"


CSDLMgr::CSDLMgr()
{
    m_pSdlWindow = NULL;
    m_pSdlTexture = NULL;
    m_pRenderer = NULL;
    m_pRenderer2 = NULL;

    m_pBtnUpTexture  = NULL;
    m_pBtnDownTexture  = NULL;
    m_pBtnBackTexture  = NULL;
    m_pBtnProgressBar = NULL;
    m_pBtnCursorTexture = NULL;
    m_pBtnRotateTexture = NULL;
    m_pFont = NULL;

    m_enOldPlayBtn = enPP_PLAY;
    m_enPlayBtn = enPP_PLAY;
    m_pAudioData = NULL;
    m_nFps=10;
    m_dbCurPts = 0;
    m_nFrameW = 0;
    m_nFrameH = 0;
    m_nTimeLen = 0;
    m_bRorate = false;
    m_pTexturePlayTime = NULL;
}

CSDLMgr::~CSDLMgr()
{
    ClearAV();
}

void CSDLMgr::ClearAV()
{
    while(!m_queAudioData.empty())
    {
        SAudioData tagData = m_queAudioData.front();

        delete[] tagData.pBuf;
        tagData.pBuf = NULL;

        m_queAudioData.pop();
    }

    if(!m_queVideoData.empty())
    {
        SVideoData tagData = m_queVideoData.front();

        delete[] tagData.pYUV;
        tagData.pYUV = NULL;

        m_queVideoData.pop();
    }

    if(m_pTexturePlayTime!=NULL)
    {
        SDL_DestroyTexture(m_pTexturePlayTime);
        m_pTexturePlayTime = NULL;
    }
}

int  CSDLMgr::Init(int nW,int nH,int nFps,int64_t nTimeLen)
{
    if(nW<=0||nH<=0||nFps<=0)
    {
        return -1;
    }

    m_nFrameW = nW;
    m_nFrameH = nH;
    m_nFps = nFps;
    m_nTimeLen = nTimeLen;
    if(TTF_Init()!=-1) {
        m_pFont=TTF_OpenFont("simfang.ttf", 40);
        if(m_pFont==NULL)
        {
            LOGE("TTF_OpenFont  error!");
        }
    }


    //初始化SDL
    if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER)) {
        LOGE("SDL_Init failed %s" ,SDL_GetError());
        return -2;
    }

    //设置window属性
    m_pSdlWindow = SDL_CreateWindow("Convexd_SDL",SDL_WINDOWPOS_UNDEFINED,SDL_WINDOWPOS_UNDEFINED,
                                    m_nFrameW, m_nFrameH,SDL_WINDOW_RESIZABLE|SDL_WINDOW_FULLSCREEN|SDL_WINDOW_OPENGL);

    //m_nFrameH, m_nFrameW,SDL_WINDOW_FULLSCREEN|SDL_WINDOW_OPENGL);
    if(!m_pSdlWindow) {
        LOGE("SDL: could not set video mode - exiting\n");
        return -3;
    }


//test
    //SDL_Surface *pWinSurface = SDL_LoadBMP("textbackground.bmp");//SDL_GetWindowSurface(m_pSdlWindow);
    //DrawText(pWinSurface,m_pFont,"abcdefg");

    SDL_GetWindowSize(m_pSdlWindow,&m_nDevW,&m_nDevH);
    LOGE("SDL_GetWindowSize m_nDevW=%d  m_nDevH=%d" ,m_nDevW,m_nDevH);

    //create renderer and set parameter
    m_pRenderer = SDL_CreateRenderer(m_pSdlWindow,-1,0);

#if BUFFER_FMT_YUV
    Uint32 sdl_out_fmt = SDL_PIXELFORMAT_IYUV;
#else
    Uint32 sdl_out_fmt = SDL_PIXELFORMAT_RGBA32;
#endif
    //Allocate a place to put our yuv image on that screen,set sdl_display_resolution
    m_pSdlTexture = SDL_CreateTexture(m_pRenderer,
                                   sdl_out_fmt,SDL_TEXTUREACCESS_STREAMING,
               m_nFrameW, m_nFrameH);
            //m_nFrameH, m_nFrameW);
    LOGI("SDL_CreateTexture w=%d h=%d",m_nFrameW, m_nFrameH);
    //默认全屏可以不用设置
//    sdlRect.x = 0;
//    sdlRect.y = 0;
//    sdlRect.w = SCREEN_W;
//    n.h = SCREEN_H;

    //SDL button
    m_pRenderer2 = m_pRenderer;
//    SDL_Texture *    pBtnUpTexture = LoadImage("p.bmp");
//    SDL_Texture *    pBtnDownTexture = LoadImage("s.bmp");
    m_pBtnUpTexture = LoadTexture(m_pRenderer,"play.bmp",SDL_TRUE);
    m_pBtnDownTexture = LoadTexture(m_pRenderer,"pause.bmp",SDL_TRUE);
    m_pBtnBackTexture = LoadTexture(m_pRenderer,"back.bmp",SDL_TRUE);
    m_pBtnRotateTexture = LoadTexture(m_pRenderer,"rotate.bmp",SDL_TRUE);
    m_pBtnProgressBar = LoadTexture(m_pRenderer,"progressbar.bmp",SDL_TRUE);
    m_pBtnCursorTexture = LoadTexture(m_pRenderer,"cursor.bmp",SDL_TRUE);

    SDL_QueryTexture(m_pBtnUpTexture, NULL, NULL, &m_rectPlayPauseBtn.w, &m_rectPlayPauseBtn.h);
    SDL_QueryTexture(m_pBtnBackTexture, NULL, NULL, &m_rectBackBtn.w, &m_rectBackBtn.h);
    SDL_QueryTexture(m_pBtnRotateTexture, NULL, NULL, &m_rectRotateBtn.w, &m_rectRotateBtn.h);
    SDL_QueryTexture(m_pBtnRotateTexture, NULL, NULL, &m_rectProgressBtn.w, &m_rectProgressBtn.h);
    LOGI("PlayPauseBtn.w=%d,PlayPauseBtn.h=%d,BackBtn.w=%d,BackBtn.h=%d,RotateBtn.w=%d,RotateBtn.h=%d",
         m_rectPlayPauseBtn.w,m_rectPlayPauseBtn.h,
         m_rectBackBtn.w,m_rectBackBtn.h,
         m_rectRotateBtn.w,m_rectRotateBtn.h);

    int nPosProgressH = m_nDevH-m_rectPlayPauseBtn.h-100;
    m_rectProgressBtn.x = 0;
    m_rectProgressBtn.y = nPosProgressH;

    return  0;
}

bool CSDLMgr::NeedExit()
{
    SDL_Event event;
    SDL_PollEvent(&event);
//    if(event.type == SDL_QUIT || event.type == SDL_KEYDOWN || event.type == SDL_FINGERDOWN)
//    {
//        return true;
//    }

    if(event.type>=0x100 && event.type<=0x8000)
        //LOGI("event type is 0x%x",event.type);

        switch(event.type)
        {
            case SDL_KEYDOWN:
            case SDL_KEYUP:
            case SDL_QUIT:
                return true;
            case SDL_FINGERDOWN:
            {
                //LOGI("event type is SDL_FINGERDOWN");
            }
                break;
            case SDL_FINGERUP:
            {
                //LOGI("event type is SDL_FINGERUP");
            }
                break;
            case SDL_MOUSEBUTTONDOWN:
            {
                SDL_Point poi;
                poi.x = event.button.x;
                poi.y = event.button.y;
                if(SDL_PointInRect(&poi,&m_rectPlayPauseBtn)==SDL_TRUE)
                {
                    LOGI("event type is SDL_MOUSEBUTTONDOWN,x=%d,y=%d",event.button.x,event.button.y);
                } else if(SDL_PointInRect(&poi,&m_rectBackBtn)==SDL_TRUE)
                {

                }else if(SDL_PointInRect(&poi,&m_rectRotateBtn)==SDL_TRUE)
                {

                }
            }
                break;
            case SDL_MOUSEBUTTONUP:
            {
                SDL_Point poi;
                poi.x = event.button.x;
                poi.y = event.button.y;
                LOGI("event type is SDL_MOUSEBUTTONUP,x=%d,y=%d; back x=%d,y=%d; rotate  x=%d,y=%d",
                     event.button.x,event.button.y,
                m_rectBackBtn.x,m_rectBackBtn.y,m_rectRotateBtn.x,m_rectRotateBtn.y);
                //点击button rect
                if(SDL_PointInRect(&poi,&m_rectPlayPauseBtn)==SDL_TRUE)
                {
                    LOGI("event type is SDL_MOUSEBUTTONUP,x=%d,y=%d",event.button.x,event.button.y);
                    //如果点击在按钮内部，play 和pause状态相互切换
                    if(m_enPlayBtn!=enPP_PLAY)
                    {
                        m_enPlayBtn = enPP_PLAY;
                    } else
                    {
                        m_enPlayBtn = enPP_PAUSEING;
                    }
                }else if(SDL_PointInRect(&poi,&m_rectBackBtn)==SDL_TRUE)
                {
                    //exit
                    return true;
                }else if(SDL_PointInRect(&poi,&m_rectRotateBtn)==SDL_TRUE)
                {
                    m_bRorate = !m_bRorate;
                }
                else {
                    //如果点击在按钮外部，显示和隐藏按钮动作切换
                    if (m_enPlayBtn == enPP_NONE) {
                        m_enPlayBtn = m_enOldPlayBtn;
                    }
                    else{
                        m_enOldPlayBtn = m_enPlayBtn;
                        m_enPlayBtn = enPP_NONE;
                    }
                }
            }
                break;
            case SDL_WINDOWEVENT:
            {
                LOGI("event.window.event=0x%x,event.window.type=0x%x",event.window.event,event.window.type);
                if(SDL_WINDOWEVENT_SIZE_CHANGED==event.window.event)
                {
                    int DevW,DevH;
                    SDL_GetWindowSize(m_pSdlWindow,&DevW,&DevH);
                    LOGI("SDL_WINDOWEVENT_SIZE_CHANGED  DevW=%d,DevH=%d",DevW,DevH);
                }
            }
            break;
        }

    return false;
}

bool CSDLMgr::NeedPlayCtrl()
{
    if(m_enPlayBtn==enPP_PAUSE || (m_enOldPlayBtn==enPP_PAUSE && m_enPlayBtn==enPP_NONE))
    {
        LOGI("event play button state is g_enOldPlayBtn=%d, g_enPlayBtn=%d",m_enOldPlayBtn,m_enPlayBtn);
        return  false;
    }
    return  true;
}

int CSDLMgr::InputVideoData(uint8_t *pY,int nYLen,uint8_t *pU,int nULen,uint8_t *pV,int nVLen, double pts)
{
    SVideoData tagData;
    tagData.pYUV = new uint8_t[nYLen*m_nFrameH*3/2];
    tagData.nYLen = nYLen;
    tagData.nULen = nULen;
    tagData.nVLen = nVLen;
    tagData.pts = pts;

    uint8_t  *pYY = tagData.pYUV;
    memcpy(pYY,pY,nYLen*m_nFrameH);

    uint8_t  *pUU = pYY+nYLen*m_nFrameH;
    memcpy(pUU,pU,nULen*m_nFrameH/2);

    uint8_t  *pVV = pUU+nULen*m_nFrameH/2;
    memcpy(pVV,pV,nVLen*m_nFrameH/2);
            ;
    m_queVideoData.push(tagData);

    double duration = (pts-m_dbCurPts)*1000;//ms
    double stdDuration = 1000/m_nFps;

    //缓存大于5个
    if(m_queVideoData.size()>=5)
    {
        //LOGI("DrawYUV Delay duration 1=%f",duration);
        duration=duration>stdDuration?stdDuration:duration;
        //LOGI("DrawYUV Delay duration 2=%f  pts=%f,audio pts=%f  m_queVideoData.size()=%d",duration,pts,m_dbCurPts,m_queVideoData.size());

        int nAudioQueSize = m_queAudioData.size();
        //音频队列有5个以上缓存，则正常休眠；2个以上则加速获取；小于2个，最快获取
        if(nAudioQueSize>5)
            SDL_Delay(duration);
        else if(nAudioQueSize>2)
            SDL_Delay(duration/2);

    } else{
        //继续读数据
        if(duration>stdDuration/5)
        {
            return -1;
        }

        SDL_Delay(duration);
    }


    SVideoData tagUseData = m_queVideoData.front();

    uint8_t  *pYYY=tagUseData.pYUV;
    uint8_t  *pUUU=pYYY+tagUseData.nYLen*m_nFrameH;
    uint8_t  *pVVV=pUUU+tagUseData.nULen*m_nFrameH/2;

    DrawYUV(pYYY,tagUseData.nYLen,
            pUUU,tagUseData.nULen,
            pVVV,tagUseData.nVLen,tagUseData.pts);

    delete[] tagUseData.pYUV;
    tagUseData.pYUV = NULL;

   m_queVideoData.pop();

    return  0;
}

int CSDLMgr::DrawText(int x,int y, const char* text)
{
    SDL_Color color2={255,255,255};
    SDL_Surface * pTextSurface = TTF_RenderText_Blended(m_pFont,text,color2);
    //创建文本纹理
    if(m_pTexturePlayTime!=NULL)
    {
        SDL_DestroyTexture(m_pTexturePlayTime);
        m_pTexturePlayTime = NULL;
    }

    m_pTexturePlayTime = SDL_CreateTextureFromSurface(m_pRenderer, pTextSurface);
    SDL_FreeSurface(pTextSurface);
    ApplySurface(x, y, m_pTexturePlayTime, m_pRenderer);
    return 0;
#if 0
    //创建文本表面
    SDL_Color color2={255,255,255};
    SDL_Surface * pTextSurface = TTF_RenderText_Blended(m_pFont,text,color2);
    //创建文本纹理
    if(m_pTexturePlayTime!=NULL)
    {
        SDL_DestroyTexture(m_pTexturePlayTime);
        m_pTexturePlayTime = NULL;
    }

    m_pTexturePlayTime = SDL_CreateTextureFromSurface(m_pRenderer, pTextSurface);
    SDL_FreeSurface(pTextSurface);
//清理窗口渲染器
    //SDL_RenderClear(m_pRenderer);
    Uint32 nFormat;
    int access,texWidth,texHeight;
    SDL_QueryTexture(m_pTexturePlayTime, &nFormat, &access, &texWidth, &texHeight);
    //设置纹理的数据
    SDL_Rect srcrect;
    srcrect.x = 0;
    srcrect.y = 0;
    srcrect.w = texWidth;
    srcrect.h = texHeight;
//texWidth=160;texHeight=41
    SDL_Rect destrect;
    destrect.x = x;
    destrect.y = y;
    destrect.w = texWidth;
    destrect.h = texHeight;

    //将文本纹理复制到窗口渲染器
    //SDL_RenderCopy(m_pRenderer, m_pTexturePlayTime, &srcrect, &destrect);
    //ApplySurface(x, y, m_pTexturePlayTime, m_pRenderer);
#endif
}

void CSDLMgr::DrawButton(int64_t pts)
{
    //draw button
    if (m_enPlayBtn==enPP_PLAY)
    {
        m_rectPlayPauseBtn.x = (m_nDevW-m_rectPlayPauseBtn.w)/2;
        m_rectPlayPauseBtn.y = m_nDevH-m_rectPlayPauseBtn.h-10;
        ApplySurface(m_rectPlayPauseBtn.x, m_rectPlayPauseBtn.y, m_pBtnUpTexture, m_pRenderer);
        //ApplySurface(m_rectPlayPauseBtn.x, m_rectPlayPauseBtn.y, m_pBtnProgressBar, m_pRenderer);
    }
    else if (m_enPlayBtn==enPP_PAUSEING)
    {
        m_enPlayBtn = enPP_PAUSE;
        m_rectPlayPauseBtn.x = (m_nDevW-m_rectPlayPauseBtn.w)/2;
        m_rectPlayPauseBtn.y = m_nDevH-m_rectPlayPauseBtn.h-10;
        ApplySurface(m_rectPlayPauseBtn.x, m_rectPlayPauseBtn.y, m_pBtnDownTexture, m_pRenderer);
    }

    if (m_enPlayBtn!=enPP_NONE)
    {
        m_rectBackBtn.x=0;
        m_rectBackBtn.y=0;
        ApplySurface(m_rectBackBtn.x, m_rectBackBtn.y, m_pBtnBackTexture, m_pRenderer);

        m_rectRotateBtn.x = m_nDevW-m_rectPlayPauseBtn.w;
        m_rectRotateBtn.y = 0;
        ApplySurface(m_rectRotateBtn.x, m_rectRotateBtn.y, m_pBtnRotateTexture, m_pRenderer);

        int64_t  nCurTime = pts*1000;
        //换算成百分比
        double  fCurProgress = nCurTime*m_nDevW*1000/m_nTimeLen;
        int nPosProgressH = m_nDevH-m_rectPlayPauseBtn.h-100;
        m_rectProgressBtn.x = 0;
        m_rectProgressBtn.y = nPosProgressH;
        ApplySurface(m_rectProgressBtn.x, m_rectProgressBtn.y, m_pBtnProgressBar, m_pRenderer);
        ApplySurface(fCurProgress, m_rectProgressBtn.y, m_pBtnCursorTexture, m_pRenderer);
        //LOGI("pts=%f,timelen=%lld,fCurProgress=%f,m_nDevW=%d",pts,m_nTimeLen,fCurProgress,m_nDevW);
    }

    SDL_RenderPresent(m_pRenderer);
}

int CSDLMgr::DrawYUV(uint8_t *pY,int nYLen,uint8_t *pU,int nULen,uint8_t *pV,int nVLen, double pts)
{
#if (BUFFER_FMT_YUV == 1)

    SDL_UpdateYUVTexture(m_pSdlTexture, /*(const SDL_Rect *)&sdlRect*/NULL, pY, nYLen,
                                         pU,nULen,
                                         pV,nVLen);
#else
    SDL_UpdateTexture(sdlTexture,NULL,pFrame_out->data[0],pCodecCtx->width*4);  //4通道：pitch = width×4
#endif

    SDL_RenderClear(m_pRenderer);



#if 0
    SDL_Rect rectShow;
                    rectShow.x = 0;
                    rectShow.y = 0;
                    rectShow.w = pCodecCtx->width;
                    rectShow.h = pCodecCtx->height;
                    SDL_RenderCopy(renderer, sdlTexture, &rectShow, NULL);
#else
//    rectDst.w = m_nFrameH;
//    rectDst.h = m_nFrameW;
//    rectDst.y = 0;

//    SDL_Point poi;
//    poi.x = m_nDevW/2;
//    poi.y = m_nDevH/2;
//    poi.x = 640;//m_nDevW/2;
//    poi.y = 360;//m_nDevH/2;
    double angle = 0;
    //if(m_nFrameW>m_nFrameH)
    if(m_bRorate==true)
    {
        angle = 90;
        //test
        SDL_Rect rectS;
        rectS.x = 0;
        rectS.y = 0;
        rectS.w = m_nFrameW;
        rectS.h = m_nFrameH;

        SDL_Rect rectD;
        rectD.x = -300;
        rectD.h = (m_nDevW-rectD.x*2)*m_nFrameH/m_nFrameW;
        rectD.y = (m_nDevH-rectD.h)/2;
        rectD.w = rectD.h*m_nFrameW/m_nFrameH;

        SDL_RenderCopyEx(m_pRenderer,
                         m_pSdlTexture,
                //NULL,//&rectSrc,//srcrect代表我们将要旋转的texture中的某个矩形区域，如果为NULL则表示将会旋转整个texture图片
                         &rectS,
                //&rectDst,
                //NULL,
                         &rectD,
                         angle,//旋转的角度
                //&poi,//以中心点旋转
                         NULL,
                         SDL_FLIP_NONE);
    } else
    {
        SDL_Rect rectDst;

        //竖屏播放
        rectDst.x = 0;
        rectDst.w = m_nDevW;
        rectDst.h = m_nFrameH*m_nDevW/m_nFrameW;
        rectDst.y = (m_nDevH-rectDst.h)/2;

        SDL_RenderCopyEx(m_pRenderer,
                         m_pSdlTexture,
                         NULL,//&rectSrc,//srcrect代表我们将要旋转的texture中的某个矩形区域，如果为NULL则表示将会旋转整个texture图片
                         &rectDst,
                         angle,//旋转的角度
                         NULL,
                         SDL_FLIP_NONE);
    }

    //m_nDevW=1080,m_nDevH=1704
    //LOGI("m_nDevW=%d,m_nDevH=%d",m_nDevW,m_nDevH);

#endif

    std::string strTime;
    ToTimeStr(pts*1000000,strTime);
    //DrawText(m_rectProgressBtn.x,m_rectProgressBtn.y+m_rectProgressBtn.h,strTime.c_str());
    //ApplySurface(m_rectProgressBtn.x, m_rectProgressBtn.y+m_rectProgressBtn.h, m_pTexturePlayTime, m_pRenderer);

    DrawText(m_rectProgressBtn.x,m_rectProgressBtn.y+m_rectProgressBtn.h,strTime.c_str());
    DrawText(m_nDevW-300,m_rectProgressBtn.y+m_rectProgressBtn.h,"1000");

    DrawButton(pts);

    return 0;
}

SDL_Texture* CSDLMgr::LoadImage(std::string file)
{
    SDL_Surface *loadedImage = NULL;
    SDL_Texture *texture = NULL;

    loadedImage = SDL_LoadBMP(file.c_str());   //加载图层
    if (loadedImage != NULL)
    {
        texture = SDL_CreateTextureFromSurface(m_pRenderer2, loadedImage);   //将图层转化为纹理
        SDL_FreeSurface(loadedImage);   //释放掉图层
    }
    return texture;
}

//此函数用于将纹理画到渲染器上
void CSDLMgr::ApplySurface(int x, int y, SDL_Texture *tex, SDL_Renderer *rend)
{
    SDL_Rect pos;
    //x，y是图片左上角的坐标
    pos.x = x;
    pos.y = y;
    //SDL_QueryTexture(tex, NULL, NULL, &pos.w, &pos.h);
    SDL_QueryTexture(tex, NULL, NULL, &pos.w, &pos.h);

    SDL_RenderCopy(rend, tex, NULL, &pos);   //将纹理tex画到渲染器rend
}

//将一张bmp图片转成纹理，并且设置边缘透明
SDL_Texture *CSDLMgr::LoadTexture(SDL_Renderer *renderer, const char *file, SDL_bool transparent)
{
    SDL_Surface *temp;
    SDL_Texture *texture;

    /* Load the sprite image */
    temp = SDL_LoadBMP(file);
    if (temp == NULL) {
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't load %s: %s", file, SDL_GetError());
        return NULL;
    }

    /* Set transparent pixel as the pixel at (0,0) */
    if (transparent) {
        if (temp->format->palette) {
            SDL_SetColorKey(temp, SDL_TRUE, *(Uint8 *) temp->pixels);
        } else {
            switch (temp->format->BitsPerPixel) {
                case 15:
                    SDL_SetColorKey(temp, SDL_TRUE,
                                    (*(Uint16 *) temp->pixels) & 0x00007FFF);
                    break;
                case 16:
                    SDL_SetColorKey(temp, SDL_TRUE, *(Uint16 *) temp->pixels);
                    break;
                case 24:
                    SDL_SetColorKey(temp, SDL_TRUE,
                                    (*(Uint32 *) temp->pixels) & 0x00FFFFFF);
                    break;
                case 32:
                    SDL_SetColorKey(temp, SDL_TRUE, *(Uint32 *) temp->pixels);
                    break;
            }
        }
    }

    /* Create textures from the image */
    texture = SDL_CreateTextureFromSurface(renderer, temp);
    if (!texture) {
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create texture: %s\n", SDL_GetError());
        SDL_FreeSurface(temp);
        return NULL;
    }
    SDL_FreeSurface(temp);

    /* We're ready to roll. :) */
    return texture;
}

void CSDLMgr::InitAudio(int out_sample_rate,int out_channels,int nFrameSize)
{
    //SDL_AudioSpec
    SDL_AudioSpec wanted_spec;
    wanted_spec.freq = out_sample_rate;
    wanted_spec.format = AUDIO_S16SYS;
    wanted_spec.channels = out_channels;
    wanted_spec.silence = 0;
    wanted_spec.samples = nFrameSize;
    wanted_spec.callback = (SDL_AudioCallback)fill_audio;
    wanted_spec.userdata = this;

    if (SDL_OpenAudio(&wanted_spec, NULL)<0){
        //printf("can't open audio.\n");
        return ;
    }

    if (NULL == m_pAudioData)
    {
        m_pAudioData = new Uint8[MAX_AUDIO_FRAME_SIZE];
    }

    SDL_PauseAudio(0);
}


/* The audio function callback takes the following parameters:
 * stream: A pointer to the audio buffer to be filled
 * len: The length (in bytes) of the audio buffer
 * 回调函数
*/
void  CSDLMgr::fill_audio(void *udata,Uint8 *stream,int len){
    CSDLMgr *pPlayer = (CSDLMgr*)udata;
    pPlayer->FillMyAudio(stream,len);
}

void CSDLMgr::FillMyAudio(Uint8 *stream,int len)
{
    memset(stream,0x0,len);
    if(m_queAudioData.empty())
    {
        LOGI("FillMyAudio ===================**************  queue.size=%d",m_queAudioData.size());
        //double dbPerTime = (double)(len*1000)/(double)(m_nResample*m_nChannels*2);
        //m_dbCurPts += dbPerTime*2;//音频取不到数据，说明readframe不及时，需要加快读取
        return;
    }

    //第一个元素
    SAudioData tagData = m_queAudioData.front();
    //LOGI("FillMyAudio =================== len=%d,BufLen=%d,queue.size=%d",len,tagData.nBufLen,m_queAudioData.size());

    int nLen = tagData.nBufLen;
    char *pData = tagData.pBuf;

    memcpy(stream,pData,nLen);

    m_dbCurPts = tagData.pts;

    if(tagData.pBuf!=NULL)
    {
        delete[] tagData.pBuf;
        tagData.pBuf = NULL;
    }
    //清除第一个元素
    m_queAudioData.pop();

//    if(m_queAudioData.size()<=2)
//    {
//        m_dbCurPts +=1;//音频取不到数据，说明readframe不及时，需要加快读取
//        LOGI("FillMyAudio +++++++  m_dbCurPts=%f",m_dbCurPts);
//    }
    return;

//    if (m_pAudioBufPos-m_pAudioData>=nLen-1 || m_pAudioBufPos==NULL)
//    {
//        m_pAudioBufPos = m_pAudioData;
//    }
//
//    memcpy(m_pAudioBufPos,pData,nLen);
//    m_nAudioLen += nLen;
//
//    if(m_nAudioLen<=0)        /*  Only  play  if  we  have  data  left  */
//        return;
//
//    len=(len>m_nAudioLen?m_nAudioLen:len);   /*  Mix  as  much  data  as  possible  */
//
//    memcpy(stream,m_pAudioBufPos,len);
//
//    m_pAudioBufPos += len;
//    m_nAudioLen -= len;
}

void CSDLMgr::InputAudioData(unsigned char *pData, int nLen, double pts)
{
    if(nLen<=0)
    {
        return;
    }

    SAudioData tagData;
    tagData.pBuf = new char[nLen];
    memcpy(tagData.pBuf,pData,nLen);
    tagData.nBufLen = nLen;
    tagData.pts = pts;
    m_queAudioData.push(tagData);

    //m_queAudioData
//    while(m_nAudioLen>0)
//    {
//        SDL_Delay(1);
//        LOGI("InputAudioData  SDL_Delay  ...... nLen=%d",nLen);
//    }

//    LOGI("InputAudioData...... nLen=%d",nLen);
//    if (m_pAudioBufPos-m_pAudioData>=nLen-1 || m_pAudioBufPos==NULL)
//    {
//        m_pAudioBufPos = m_pAudioData;
//    }
//
//    memcpy(m_pAudioBufPos,pData,nLen);
//    m_nAudioLen += nLen;
}

void CSDLMgr::ToTimeStr(int64_t nTime,std::string &strTime)
{
    char szTime[128]={0};
    int hours, mins, secs, us;
    secs = nTime / AV_TIME_BASE;
    us = nTime % AV_TIME_BASE;
    mins = secs / 60;
    secs %= 60;
    hours = mins/ 60;
    mins %= 60;
    //sprintf(szTime,"%02d:%02d:%02d.%02d\n", hours, mins, secs, (100 * us) / AV_TIME_BASE);
    sprintf(szTime,"%02d:%02d:%02d", hours, mins, secs);
    strTime = szTime;
}